最短路径搜索算法中Dijkstra的原理


一:简介

  这个算法用于解决图中单源最短路径问题。所谓单源节点是指给定源节点,求图中其它节点到此源节点的最短路径。如下图所示:给定源节点a,求节点b到a的最短距离。

(图来自于参考资料2)

那么如何寻找?还是以上图为例:

1)初始化:设定除源节点以外的其它所有节点到源节点的距离为INFINITE(一个很大的数),且这些节点都没被处理过。

2)从源节点出发,更新相邻节点(图中为2,3,6)到源节点的距离。然后在所有节点中选择一个最段距离的点作为当前节点。

3)标记当前节点为done(表示已经被处理过),与步骤2类似,更新其相邻节点的距离。(这些相邻节点的距离更新也叫松弛,目的是让它们与源节点的距离最小。因为你是在当前最小距离的基础上进行更新的,由于当前节点到源节点的距离已经是最小的了,那么如果这些节点之前得到的距离比这个距离大的话,我们就更新它)。

4)步骤3做完以后,设置这个当前节点已被done,然后寻找下一个具有最小代价(cost)的点,作为新的当前节点,重复步骤3.

5)如果最后检测到目标节点时,其周围所有的节点都已被处理,那么目标节点与源节点的距离就是最小距离了。如果想看这个最小距离所经过的路径,可以回溯,前提是你在步骤3里面加入了当前节点的最优路径前驱节点信息。

 看文字描述显得苍白无力,你可以结合上图,看下这个视频:http://v.youku.com/v_show/id_XMjQyOTY1NDQw.html (dijkstra演示),然后就清楚了。


二:源代码

  直接给源代码,注释很清楚,不解释。

 

Dijkstra.h
Dijkstra.c
main.c

demo:

输入文件内容:

1:2-2:3-4:5-4;
2:1-2:3-3;
3:1-4:2-3:5-6:6-7;
4:6-8;
5:1-4:3-6;
6:3-7:4-8;

格式说明:

起始节点:连接节点1-权值:连接节点2-权值:连接节点3-权值.....

图的结构:

运行结果:

 

三:总结

  Dijkstra最短路径搜索属于广度优先搜索(BFS, Breadth-First-Search),即不断去搜索当前节点的所有相邻节点,并更新它们的cost。更新的前提是认为:当前节点是目前与起始节点之间cost最小的节点,它认为自己是最优解,要想到达目的节点,经过我这里必然错不了,接着在此基础上不断去寻找其它最优路径,运用的是一种贪婪算法的思想。但是有时候并不是最优解,典型的例子就是:最小数目找零的例子,现有10元,5元,1元的纸币,如果要找15块钱,贪婪算法的结果是-10元+5元。但是如果现在假设银行发行了12元一张的纸币(银行闲的蛋疼),还用贪婪算法,结果是12+1+1+1(坑爹的,找这么多硬币!!)。但是实际上最优解仍然是10元+5元。所以有时候,具体问题要具体分析。另外,最优路径搜素还有带有启发性的A*搜索,双向广度优先搜索(BFS),它们比Dijkstra算法的搜索效率要高。改天再续。

  再说一下,我的代码中,在寻找下一个当前节点时,用了全局搜索,这显然是一个很笨的方法,复杂度太高。一般的方法都是定义一个开集,一个闭集,用来存储未处理过的节点和已被处理的节点,所以我们可以用FIFO队列去优化。参考资料1。

  

参考资料:

1,《数据结构与算法分析-c++描述》,weiss

2,http://en.wikipedia.org/wiki/Dijkstra's_algorithm

3,http://blog.chinaunix.net/uid-20662820-id-142445.html

4,http://www.rawbytes.com/dijkstras-algorithm-in-c/


  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值